#include "Axes.h"

Axes::Axes():
	mLength(10),
	mPixelSize(100)
{
	addChild(drawAxes());

	setViewport(0, 0, mPixelSize, mPixelSize);
	setProjectionMatrix(osg::Matrix::ortho2D(-mLength, mLength, -mLength, mLength));
	setRenderOrder(Camera::POST_RENDER);
	setClearMask(GL_DEPTH_BUFFER_BIT);
	setAllowEventFocus(false);
	setReferenceFrame(Transform::ABSOLUTE_RF);
}

Axes::~Axes()
{

}

void Axes::traverse(osg::NodeVisitor& nv)
{
	if (mCamera.valid() && nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
	{
		osg::Vec3f eye;
		osg::Vec3f center;
		osg::Vec3f up;

		mCamera->getViewMatrixAsLookAt(eye, center, up);
		osg::Matrixd matrix;
		matrix.makeLookAt(eye - center, osg::Vec3(0, 0, 0), up);
		this->setViewMatrix(matrix);
	}
	osg::Camera::traverse(nv);
}

osg::Node* Axes::drawAxes()
{
	osg::ref_ptr<osg::Box> box = new osg::Box(osg::Vec3(0.0f, 0.0f, 0.0f), 0.4*mLength, 0.4*mLength, 0.4*mLength);
	osg::ShapeDrawable * originPoint = new osg::ShapeDrawable(box);

	osg::ref_ptr<osg::Geometry> threeAxis = new osg::Geometry;

	osg::ref_ptr<osg::Vec3Array> vectors = new osg::Vec3Array;
	vectors->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
	vectors->push_back(osg::Vec3(mLength, 0.0f, 0.0f));
	vectors->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
	vectors->push_back(osg::Vec3(0.0f, mLength, 0.0f));
	vectors->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
	vectors->push_back(osg::Vec3(0.0f, 0.0f, mLength));
	threeAxis->setVertexArray(vectors.get());

	osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array();
	colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
	colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
	colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
	colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
	threeAxis->setColorArray(colors.get());
	threeAxis->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

	threeAxis->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 2));
	threeAxis->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 2, 2));
	threeAxis->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 4, 2));

	osg::Geode *axis = new osg::Geode;
	axis->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
	axis->getOrCreateStateSet()->setAttribute(new osg::LineWidth(3.0), osg::StateAttribute::ON);
	axis->addDrawable(threeAxis);
	axis->addDrawable(originPoint);

	return axis;
}
